package room

import (
	"errors"
	"server/common"

	"github.com/google/uuid"
	"github.com/sirupsen/logrus"
)

type RoomService struct {
	dispatcher  common.IMsgDispatcher
	serviceInfo common.ServiceInfo
	roomMgr     *RoomManager  // Assuming RoomManager is defined elsewhere
	mediaMgr    *MediaManager // Manage services and workers
}

// -------------------------------------------------------------------------------------------------
// Create a new instance of RoomService
// -------------------------------------------------------------------------------------------------
func NewRoomService(dispatcher common.IMsgDispatcher) *RoomService {
	return &RoomService{
		serviceInfo: common.ServiceInfo{
			ServiceType: common.SERVICE_TYPE_ROOM,
			ServiceId:   uuid.New().String(),
		},
		dispatcher: dispatcher,
		mediaMgr:   NewMediaManager(dispatcher),
	}
}

// -------------------------------------------------------------------------------------------------
// Init initializes the RoomService
// -------------------------------------------------------------------------------------------------
func (s *RoomService) Init() error {
	// Register the service to the dispatcher
	if err := s.dispatcher.Register(s.serviceInfo, s); err != nil {
		LOG().WithError(err).Error("failed to register RoomService with dispatcher")
		return err
	}

	s.roomMgr = NewRoomManager(s.dispatcher, s.serviceInfo, s.mediaMgr)

	LOG().Info("RoomService initialized successfully")
	return nil
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *RoomService) HandleMsg(msg common.Message, from common.ServiceInfo, connId string) error {
	LOG().WithFields(logrus.Fields{
		"msg":    common.ToJson(msg),
		"from":   from,
		"connId": connId,
	}).Info("received message in room service")

	switch msg.Cmd {
	case common.CONNECTION_CLOSED_NOTIFY:
		return s.handleConnectionClosedNotify(msg, from, connId)
	case common.USER_OFFLINE_NOTIFY:
		return s.handleUserOfflineNotify(msg, from, connId)
	// 房间管理
	case common.SFU_PREPARE_ROOM_REQ:
		return s.handlePrepareRoomReq(msg, from, connId)
	case common.SFU_JOIN_ROOM_REQ:
		return s.handleJoinRoomReq(msg, from, connId)
	case common.SFU_LEAVE_ROOM_REQ:
		return s.handleLeaveRoomReq(msg, from, connId)

	// 发布/订阅
	case common.SFU_START_PUBLISH_REQ:
		return s.handleStartPublishReq(msg, from, connId)
	case common.SFU_START_PUBLISH_ACK:
		return s.handleStartPublishAck(msg, from, connId)
	case common.SFU_STOP_PUBLISH_REQ:
		return s.handleStopPublishReq(msg, from, connId)
	case common.SFU_STOP_PUBLISH_ACK:
		return s.handleStopPublishAck(msg, from, connId)
	case common.SFU_START_SUBSCRIBE_REQ:
		return s.handleStartSubscribeReq(msg, from, connId)
	case common.SFU_STOP_SUBSCRIBE_REQ:
		return s.handleStopSubscribeReq(msg, from, connId)

	// 传输管理
	case common.SFU_CREATE_TRANSPORT_REQ:
		return s.handleCreateTransportReq(msg, from, connId)
	case common.SFU_CONNECT_TRANSPORT_REQ:
		return s.handleConnectTransportReq(msg, from, connId)
	case common.SFU_START_PRODUCE_REQ:
		return s.handleStartProduceReq(msg, from, connId)
	case common.SFU_STOP_PRODUCE_REQ:
		return s.handleStopProduceReq(msg, from, connId)

	// 服务注册
	case common.REGISTER_SERVICE_REQ:
		return s.handleRegisterServiceReq(msg, from, connId)
	}

	return errors.New("unknown message type: " + msg.Cmd)
}
